// 路由守卫
import router, { asyncRoutes } from './router'
import { getToken } from './utils/auth'
// 导入进度条插件
import NProgress from 'nprogress'
// 导入进度条样式
import 'nprogress/nprogress.css'
import store from './store'
// 修改标题方法
import getPageTitle from '@/utils/get-page-title'

const whiteList = ['/login'] // 白名单，定义没有token时可以进行跳转的页面

// 前置路由守卫
router.beforeEach(async(to, from, next) => {
  // 开启进度条效果
  NProgress.start()
  // 获取token
  const token = getToken()
  if (token) { // 登陆了
    if (to.path === '/login') {
      // 已经登陆了，但是还想跳转到登录页，强制跳转到首页
      next('/')
      NProgress.done()
    } else { // 去其他界面
      // 在去非登录界面时获取用户信息
      next()// 如果手动让cookie里token改错误,刷新以后,vuex才会从本地取出错误token
      // 刷新时,路由守卫会从 / 跳转到地址栏里路由地址,所以先让页面跳转进去
      // 执行下面请求会401,被动退出时，-才能拿到跳转后的路由地址(未遂地址给登录页面，否则next在下面,·未遂地址是/)
      document.title = getPageTitle(to.meta.title)
      if (!store.getters.name) {
        // 在定义user下的getUserInfoProfileActions方法时，该方法返回了数据，这里dispatch之后可以进行接受
        const menus = await store.dispatch('user/getUserInfoProfileActions')
        // 将接受后的权限与原本定义的权限进行过滤，匹配的就可以理解为该用户有该权限
        const filterRoutes = asyncRoutes.filter(route => {
          // 将路由的名字转换为都是小写的
          const routeName = route.children[0].name.toLowerCase()
          // 检测menus中是否包含routeName，包含的话就返回true，然后filter进行收集
          return menus.includes(routeName)
        })
        // 始终都动态添加八个路由信息
        // 始终都动态添加先8个路由规则对象
        // 知识点:路由切换匹配的路由规则对象数组存在于内存中的
        // new Router时，有一些初始的路由规则对象
        // addRoutes,会给路由表，再额外的增加一个规则对象
        // 现象:路由规则对象添加成功,但是左侧的导航不见了

        // 解决404问题，在这里添加一个404页面，
        filterRoutes.push({
          path: '*', redirect: '/404', hidden: true
        })

        router.addRoutes(filterRoutes)

        // 将动态路由传递给 mutation 方法，进行合并，用于路由展示页面左侧导航栏
        store.commit('permission/setRoutes', filterRoutes)

        // 路由再进行一次跳转，在上边的next跳转会匹配不到显示白屏，这里需要再次跳转
        next({
          path: to.path,
          replace: true // 不让回退
        })
      }
    }
  } else { // 没有登录
    if (whiteList.indexOf(to.path) !== -1) { // 地址在白名单里
      next()
    } else { // 地址不在白名单里
      next('/login')
      NProgress.done()
    }
  }
})

// 后置路由守卫
router.afterEach((res, a, b, c) => {
  // 隐藏进度条效果
  NProgress.done()
})
